function fitting = FitXe129T1Rho(obj, signalT1rho, singalPump, timerData, varargin)
    p=inputParser; p.KeepUnmatched = true;
    p.addRequired('timerData', @(x) isnumeric(x));
    p.addParameter('calibrationField', 0.1, @(x) x>0.0);
    p.addParameter('sign', -1, @(x) ismember(x, [-1 1]));
    p.addParameter('rate', 50, @(x) x>0)
    p.parse(timerData, varargin{:});
    
    calibrationCoeff = obj.SystemInfo.MainField.f0/4.7/obj.SystemInfo.MainField.bz0*p.Results.calibrationField; %Rb85
    [fitting.calibrationValue, fitting.data_t1rho] = findTrigger(signalT1rho, calibrationCoeff, p.Results.timerData);
    [fitting.result, fitting.gof, fitting.envelope] = fitenvelopt(fitting.data_t1rho, p.Results.sign);
    [fitting.resultPump, fitting.gofPump] = fitExchangePumping(singalPump, p.Results.sign);
    %%
    targetResolution = 0.01; % Hz
    L = 2^nextpow2(p.Results.rate/targetResolution);
    fList= (0:L/2)*p.Results.rate/L; Y = fft(fitting.data_t1rho.y-mean(fitting.data_t1rho.y), L);
    P2 = abs(Y/L); P1 = P2(1:L/2+1); P1(2:end-1) = 2*P1(2:end-1);
    
    fitting.fft.fList = fList;
    fitting.fft.value = P1;
    [~, fitting.fft.RabiFreq] = findpeaks(fitting.fft.value, fitting.fft.fList, 'NPeaks', 1, 'SortStr', 'descend');
end


function [calibrationValue, data_t1rho] = findTrigger(signal, calibrationField, tocList)
    tList0 = signal.getNodeData(2).x;
    data0 = signal.getNodeData(2).y;
    [~, idx] = findpeaks(diff(data0), 'Npeak', 2, 'SortStr', 'descend');
    t0 = tList0(min(idx)+1);
    tList = tList0 - t0;
    
    idxCalibration = tList>0 & tList<tocList(1);
    calibrationValue = mean(data0(idxCalibration));
    
    idxT1rho = tList >= tocList(4);
    data_t1rho.x = tList(idxT1rho) - tocList(4);
    data_t1rho.y = data0(idxT1rho)/calibrationValue*calibrationField;
end

function [result, gof, env] = fitenvelopt(data, sign)
    if nargin == 1
        sign = 1.0;
    end
    tList = data.x;
    env=envelope(sign*data.y, 3000);

    [xData, yData] = prepareCurveData( tList, env );

    % Set up fittype and options.
    ft = fittype( 'a*exp(-x/tau)+c', 'independent', 'x', 'dependent', 'y' );
    opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
    opts.Display = 'Off';
    opts.Lower = [0 0 0];
    opts.StartPoint = [0.5*max(yData) 0.5*max(yData) mean(xData)];

    % Fit model to data.
    [result, gof] = fit( xData, yData, ft, opts );
end

function [result, gof] = fitExchangePumping(signal, sign)
    data = signal.getNodeData(2);
    tList = data.x;
    sigList = sign.*data.y;

    [xData, yData] = prepareCurveData( tList, sigList );

    % Set up fittype and options.
    ft = fittype( 'a*exp(-x/tau)+c', 'independent', 'x', 'dependent', 'y' );
    opts = fitoptions( 'Method', 'NonlinearLeastSquares' );
    opts.Display = 'Off';
    opts.Lower = [0 -Inf 0];
    opts.StartPoint = [max(yData) min(yData) mean(xData)];

    % Fit model to data.
    [result, gof] = fit( xData, yData, ft, opts );
end
